
package client;

import common.Utils;
import common.packet.ClientInfo;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Box;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;
import javax.swing.SwingWorker;

/**
 *
 * @author xissburg
 */
public class LoginPanel extends javax.swing.JPanel implements GameController.EventHandler
{
    private GameController gameController;

    public LoginPanel(GameController gameController)
    {
        initComponents();

        this.gameController = gameController;

        AbstractAction action = new AbstractAction(){
            public void actionPerformed(ActionEvent e) {
                loginButtonActionPerformed(e);
            }
        };

        nameTextField.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "pressed");
        nameTextField.getActionMap().put("pressed", action);
        passwordField.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "pressed");
        passwordField.getActionMap().put("pressed", action);
        hostnameTextField.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "pressed");
        hostnameTextField.getActionMap().put("pressed", action);
        portTextField.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "pressed");
        portTextField.getActionMap().put("pressed", action);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        innerLoginPanel = new javax.swing.JPanel();
        nameLabel = new javax.swing.JLabel();
        passwordLabel = new javax.swing.JLabel();
        hostnameLabel = new javax.swing.JLabel();
        portLabel = new javax.swing.JLabel();

        setLayout(new javax.swing.BoxLayout(this, javax.swing.BoxLayout.X_AXIS));

        innerLoginPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Login"));
        innerLoginPanel.setMaximumSize(new java.awt.Dimension(260, 244));
        innerLoginPanel.setMinimumSize(new java.awt.Dimension(260, 244));
        innerLoginPanel.setPreferredSize(new java.awt.Dimension(260, 244));
        innerLoginPanel.setLayout(new javax.swing.BoxLayout(innerLoginPanel, javax.swing.BoxLayout.Y_AXIS));

        nameLabel.setLabelFor(nameTextField);
        nameLabel.setText("Name");
        nameLabel.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM);
        nameLabel.setAlignmentX(0.5F);
        nameLabel.setMaximumSize(new java.awt.Dimension(180, 20));
        nameLabel.setPreferredSize(new java.awt.Dimension(180, 20));
        innerLoginPanel.add(nameLabel);

        nameTextField.setMaximumSize(new java.awt.Dimension(180, 23));
        nameTextField.setMinimumSize(new java.awt.Dimension(180, 23));
        nameTextField.setPreferredSize(new java.awt.Dimension(6, 23));
        innerLoginPanel.add(nameTextField);

        passwordLabel.setLabelFor(passwordField);
        passwordLabel.setText("Password");
        passwordLabel.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM);
        passwordLabel.setAlignmentX(0.5F);
        passwordLabel.setMaximumSize(new java.awt.Dimension(180, 20));
        passwordLabel.setPreferredSize(new java.awt.Dimension(180, 20));
        innerLoginPanel.add(passwordLabel);

        passwordField.setMaximumSize(new java.awt.Dimension(180, 23));
        passwordField.setMinimumSize(new java.awt.Dimension(180, 23));
        passwordField.setPreferredSize(new java.awt.Dimension(180, 23));
        innerLoginPanel.add(passwordField);

        hostnameLabel.setLabelFor(hostnameTextField);
        hostnameLabel.setText("Hostname");
        hostnameLabel.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM);
        hostnameLabel.setAlignmentX(0.5F);
        hostnameLabel.setMaximumSize(new java.awt.Dimension(180, 20));
        hostnameLabel.setPreferredSize(new java.awt.Dimension(180, 20));
        innerLoginPanel.add(hostnameLabel);

        hostnameTextField.setText("localhost");
        hostnameTextField.setMaximumSize(new java.awt.Dimension(180, 23));
        hostnameTextField.setMinimumSize(new java.awt.Dimension(180, 23));
        hostnameTextField.setPreferredSize(new java.awt.Dimension(180, 23));
        innerLoginPanel.add(hostnameTextField);

        portLabel.setLabelFor(portTextField);
        portLabel.setText("Port");
        portLabel.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM);
        portLabel.setAlignmentX(0.5F);
        portLabel.setMaximumSize(new java.awt.Dimension(180, 20));
        portLabel.setPreferredSize(new java.awt.Dimension(180, 20));
        innerLoginPanel.add(portLabel);

        portTextField.setText("4004");
        portTextField.setMaximumSize(new java.awt.Dimension(180, 23));
        portTextField.setMinimumSize(new java.awt.Dimension(180, 23));
        portTextField.setPreferredSize(new java.awt.Dimension(180, 23));
        innerLoginPanel.add(portTextField);
        innerLoginPanel.add(Box.createRigidArea(new Dimension(0, 14)));

        loginButton.setText("Login");
        loginButton.setAlignmentX(0.5F);
        loginButton.setPreferredSize(new java.awt.Dimension(68, 23));
        loginButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                loginButtonActionPerformed(evt);
            }
        });
        innerLoginPanel.add(loginButton);

        add(javax.swing.Box.createHorizontalGlue());
        add(innerLoginPanel);
        add(javax.swing.Box.createHorizontalGlue());
    }// </editor-fold>//GEN-END:initComponents

    private void loginButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_loginButtonActionPerformed
        //Get the values in the fields
        final String name = nameTextField.getText();

        if(name == null || name.length() <= 0)
        {
            JOptionPane.showMessageDialog(LoginPanel.this, "Name cannot be empty.",
                    "Error", JOptionPane.ERROR_MESSAGE);
            return;
        }

        final char[] password = passwordField.getPassword();

        final String hostname = hostnameTextField.getText();

        if(hostname == null || hostname.length() <= 0)
        {
            JOptionPane.showMessageDialog(LoginPanel.this, "Hostname cannot be empty.",
                    "Error", JOptionPane.ERROR_MESSAGE);
            return;
        }

        String sPort = portTextField.getText();

        if(sPort == null || sPort.length() <= 0)
        {
            JOptionPane.showMessageDialog(LoginPanel.this, "Port cannot be empty.",
                    "Error", JOptionPane.ERROR_MESSAGE);
            return;
        }
        
        int tport = 4004;

        try {
            tport = Integer.parseInt(sPort);
        } catch (NumberFormatException ex) {
            JOptionPane.showMessageDialog(LoginPanel.this, "Invalid value for Port field.",
                    "Error", JOptionPane.ERROR_MESSAGE);
            return;
        }

        final int port = tport;//funny hack

        //Disable all fields and the loginButton
        setComponentsEnabled(false);
        loginButton.setText("Connecting...");

        //Worker: connects with the server and performs the authentication process
        new SwingWorker<Void, Void>()
        {
            @Override
            protected Void doInBackground()
            {
                gameController.login(name, new String(password), hostname, port);
                return null;
            }
        }.execute();
    }//GEN-LAST:event_loginButtonActionPerformed

    /**
     * Enables/disables all relevant components of the login panel, namely:
     * nameTextField, passwordField, hostnameTextField, portTextField and loginButton.
     *
     * @param enabled
     */
    private void setComponentsEnabled(boolean enabled)
    {
        nameTextField.setEnabled(enabled);
        passwordField.setEnabled(enabled);
        hostnameTextField.setEnabled(enabled);
        portTextField.setEnabled(enabled);
        loginButton.setEnabled(enabled);
    }
    
    public void error(final String message)
    {
        Utils.runInEDT(new Runnable() {
            public void run() {
                JOptionPane.showMessageDialog(LoginPanel.this, message,
                    "Error", JOptionPane.ERROR_MESSAGE);
                loginButton.setText("Login");
                setComponentsEnabled(true);
            }
        });
    }

    public void connected()
    {
        Utils.runInEDT(new Runnable() {
            public void run() {
                loginButton.setText("Connected");
            }
        });
    }

    public void gameCreated() {
        //Wait this call to return so that the login process will only continue
        //after the gamePanel is created. If we don't wait we'll lose other events
        //called by the gameController through the EventHandler interface.
        Utils.runInEDT(new Runnable() {
            public void run() {
                GamePanel gamePanel = new GamePanel(gameController);
                gameController.setEventHandler(gamePanel);

                //Set it to the screen
                Container parent = LoginPanel.this.getParent();
                parent.removeAll();
                parent.add(gamePanel);
                parent.validate();
                gamePanel.repaint();
            }
        }, true);
    }

    public void disconnected(final String message)
    {
        if(message != null && message.length()>0)
            error(message);
    }

    public void addClient(ClientInfo clientInfo) {}
    public void clientJoined(ClientInfo clientInfo) {}
    public void clientQuit(ClientInfo clientInfo) {}
    public void chatMessage(String message) {}
    

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel hostnameLabel;
    private final javax.swing.JTextField hostnameTextField = new javax.swing.JTextField();
    private javax.swing.JPanel innerLoginPanel;
    private final javax.swing.JButton loginButton = new javax.swing.JButton();
    private javax.swing.JLabel nameLabel;
    private final javax.swing.JTextField nameTextField = new javax.swing.JTextField();
    private final javax.swing.JPasswordField passwordField = new javax.swing.JPasswordField();
    private javax.swing.JLabel passwordLabel;
    private javax.swing.JLabel portLabel;
    private final javax.swing.JTextField portTextField = new javax.swing.JTextField();
    // End of variables declaration//GEN-END:variables
}
